package com.zb.task;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.zb.config.MQConfig;
import com.zb.entity.TbSeckillGoodsModel;
import com.zb.entity.TbSeckillOrderModel;
import com.zb.service.TbSeckillGoodsService;
import com.zb.vo.SeckillStatus;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * <p>添加描述信息</p>
 *
 * @author 李柯
 * @since 2022年11月17日 10:58
 */
@Component
public class MultiThreadingCreateOrder {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private TbSeckillGoodsService tbSeckillGoodsService;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private RedissonClient redissonClient;

    @Async
    public void createOrder(){
        System.out.println("异步开始创建订单");
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //获取排队的用户
        SeckillStatus seckillQueue = (SeckillStatus) redisTemplate.boundListOps("seckillQueue").rightPop();
        String id = seckillQueue.getGoodsId();
        String time = seckillQueue.getTime();
        String username = seckillQueue.getUsername();
        //获取用户的状态
        SeckillStatus seckillStatus = (SeckillStatus) redisTemplate.boundHashOps("seckillStatus").get(username);
        //从商品数量队列中获取值，有值表示具备秒杀条件，没值表示没有库存
        Object val = redisTemplate.boundListOps("seckillGoodsCountList:" + id).rightPop();
        if (val==null){
            System.out.println("没有库存");
            //修改用户对商品的秒杀状态，活动失败
            seckillStatus.setStatus(4);
            redisTemplate.boundHashOps("seckillStatus").put(username, seckillStatus);
            return ;
        }

        String  lockey="lock:"+id;
        RLock lock = redissonClient.getLock(lockey.intern());
        lock.lock(10, TimeUnit.SECONDS);
        //查询秒杀的商品
        TbSeckillGoodsModel goodsModel = (TbSeckillGoodsModel) redisTemplate.boundHashOps("seckillGoods:" + time).get(id);

        TbSeckillOrderModel orderModel = new TbSeckillOrderModel();
        orderModel.setId(IdWorker.getId());
        orderModel.setSeckillId(Long.parseLong(id));
        orderModel.setMoney(goodsModel.getPrice());
        orderModel.setUserId(username);
        orderModel.setCreateTime(new Date());
        orderModel.setPayTime(new Date());
        orderModel.setStatus("1");

        redisTemplate.boundHashOps("seckillOrder").put(username,orderModel);
        goodsModel.setStockCount(goodsModel.getStockCount()-1);

        Long size = redisTemplate.boundListOps("seckillGoodsCountList:" + id).size();

        System.out.println("size==================>" + size);
        if (size <= 0) {
            goodsModel.setStockCount(0);
            tbSeckillGoodsService.updateById(goodsModel);
        }
        redisTemplate.boundHashOps("seckillGoods:" + time).put(id,goodsModel);
        //修改用户对商品的秒杀状态 ,秒杀成功但是没有支付
        seckillStatus.setStatus(2);
        redisTemplate.boundHashOps("seckillStatus").put(username, seckillStatus);
        System.out.println("异步结束订单");

        rabbitTemplate.convertAndSend(MQConfig.ONESECKILL_EXCHANGE, MQConfig.ONESECKILL_ROUTING, username, new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                message.getMessageProperties().setExpiration(20000 + "");
                return message;
            }
        });
        lock.unlock();

    }
}
